package com.example.demo.Master;

import com.example.demo.Entity.ChunkInfo;
import com.example.demo.Entity.FSFolder;
import com.example.demo.Entity.ServerInfo;

import java.net.InetAddress;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.Map;

/**
 * 主服务器逻辑
 * @author xyt
 */
public class MasterBase {


  private HashMap<String, ServerInfo> chunkServerMap;        //块服务器列表及其相关信息
  private FSFolder root;                                      //根目录,树形文件系统下的文件提供对应ChunkInfo的路径信息
  private HashMap<String,ChunkInfo> chunkInfoMap;  //虚拟文件系统的具体文件路径对应ChunkInfo的映射


  public FSFolder getRoot() {
    return root;
  }

  public void setRoot(FSFolder root) {
    this.root = root;
  }

  public HashMap<String, ServerInfo> getChunkServerMap() {
    return chunkServerMap;
  }

  public void setChunkServerMap(HashMap<String, ServerInfo> chunkServerMap) {
    this.chunkServerMap = chunkServerMap;
  }

  public HashMap<String, ChunkInfo> getChunkInfoMap() {
    return chunkInfoMap;
  }

  public void setChunkInfoMap(HashMap<String, ChunkInfo> chunkInfoMap) {
    this.chunkInfoMap = chunkInfoMap;
  }

  public MasterBase(){
    this.chunkServerMap = new HashMap<String,ServerInfo>();
    this.root = new FSFolder();
  }

  public synchronized void addServer(String serverName,InetAddress addr,int port){
    //网络通信方面待补充

    ServerInfo serverInfo = new ServerInfo(addr,port);
    chunkServerMap.put(serverName,serverInfo);
  }

  public synchronized void removeServer(String serverName){
    //网络通信方面待补充

    chunkServerMap.remove(serverName);
  }

  public void heartBeat(){
    //检查是否有块服务器宕机(待补充)
    for(Map.Entry<String,ServerInfo> entry:chunkServerMap.entrySet()){
      //检查宕机代码if(){
        serverFailHandle(entry.getKey());
      //}
    }

    //至于检查块就不做了，等到用户需要下载的时候检查Hash值再替用副本和修改主副备份位置
  }


  public void serverFailHandle(String serverName){
    for(Map.Entry<String,ChunkInfo> entry:chunkInfoMap.entrySet()) {
      if(entry.getValue().getServerName().equals(serverName)){  //如果主块在宕机的服务器中
        chunkFailHandle(entry.getValue());
      }
    }

    chunkServerMap.remove(serverName);                        //从块服务器列表中移除
  }

  public void chunkFailHandle(ChunkInfo chunkInfo){
    chunkInfo.setServerName(chunkInfo.getFirstCopyServerName());          //使用第一个副本取代主副本
    chunkInfo.setFirstCopyServerName(chunkInfo.getSecondCopyServerName()); //将第二副本改为第一副本
    chunkInfo.removeSecondCopyServer();                                   //移除第二副本
  }
}
